package fi.tikesos.validator.jena.rdfa;

import java.io.FileNotFoundException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Hashtable;

import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class LocalEntityResolver implements EntityResolver {

    private static Hashtable<String,String> entityHashtable = new Hashtable<String, String>();

    private static URL DTD_ROOT_URL = LocalEntityResolver.class.getResource("/dtds");
    
    public LocalEntityResolver() throws FileNotFoundException {
        if (DTD_ROOT_URL != null) return;
        throw new FileNotFoundException("Could not find dtds folder " + DTD_ROOT_URL);
    }

    public InputSource resolveEntity(String publicId, String systemId)
            throws SAXException {
        String entity = null;

        if ( publicId != null && publicId.startsWith("-//W3C//")) {
            if ( "-//W3C//DTD XHTML+RDFa 1.0//EN".equals(publicId)) {
                systemId = DTD_ROOT_URL + "/www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd";
            }   else {
                systemId = convertFromFilePath(systemId);
            }
        }

        if (publicId != null) {
            entity = (String) entityHashtable.get(publicId);
        }
        
        if (systemId != null && entity == null ) {
            entity = (String) entityHashtable.get(systemId);
        }

        if (entity == null && systemId != null) {
            if (systemId.startsWith("http://")) {
                entity = convertToSystemPath(systemId);

            } else {
                entity = systemId;
            }
            
           try {
                if (publicId != null) {
                    LocalEntityResolver.register(publicId, entity);
                } else {
                    LocalEntityResolver.register(systemId, entity);
                }
         } catch (MalformedURLException e) {
              System.out.println(e);  
            }
        }

        if (entity == null) {

            return null;
        }


        return new InputSource(entity);
    }

    static String convertToSystemPath(String systemId) {
        String entity;
        String dtdPath = systemId.substring("http://".length());
        int pathIdx = dtdPath.indexOf("/");
        String dtdHost = dtdPath.substring(0, pathIdx);
        entity = dtdPath.substring(pathIdx);
        entity = dtdHost + entity;
        if ( !DTD_ROOT_URL.toString().endsWith("/")) entity = "/" + entity;
        return DTD_ROOT_URL + entity;
    }

    static String convertFromFilePath(String systemId) {
        String rootUrlStr = LocalEntityResolver.class.getResource("/").toString();
        if ( !systemId.startsWith("file:/")) return systemId;
        int idx = systemId.indexOf(rootUrlStr);
        if ( idx != 0) return systemId;
        String entityUri = systemId.substring(rootUrlStr.length());
        if ( entityUri.startsWith("dtds/") ) return systemId;
        if ( !DTD_ROOT_URL.toString().endsWith("/")) entityUri = "/" + entityUri;
        return DTD_ROOT_URL + entityUri;
    }


    public static void register(String publicId, String entityURL) throws MalformedURLException {
        entityHashtable.put(publicId, entityURL);
    }

}

